package com.hospital.workstation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ObjectUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.hospital.common.core.domain.R;
import com.hospital.common.core.domain.model.LoginUser;
import com.hospital.common.helper.LoginHelper;
import com.hospital.common.utils.StringUtils;
import com.hospital.common.core.page.TableDataInfo;
import com.hospital.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hospital.workstation.constant.DictConstants;
import com.hospital.workstation.domain.*;
import com.hospital.workstation.domain.bo.MedicalRecordBo;
import com.hospital.workstation.domain.bo.PharmaceuticalCareDetailBo;
import com.hospital.workstation.domain.vo.MedicalRecordVo;
import com.hospital.workstation.domain.vo.PatientBaseInfoVo;
import com.hospital.workstation.domain.vo.PharmaceuticalCareDetailVo;
import com.hospital.workstation.mapper.*;
import com.hospital.workstation.utils.PoiTlUtils;
import javafx.beans.binding.ObjectExpression;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.patterns.IfPointcut;
import org.ddr.poi.html.HtmlRenderPolicy;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import com.hospital.workstation.domain.bo.PharmaceuticalCareBo;
import com.hospital.workstation.domain.vo.PharmaceuticalCareVo;
import com.hospital.workstation.service.IPharmaceuticalCareService;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 药学监护记录Service业务层处理
 *
 * @author whb
 * @date 2023-02-15
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class PharmaceuticalCareServiceImpl implements IPharmaceuticalCareService {

    private final PharmaceuticalCareMapper baseMapper;
    private final PharmaceuticalCareDetailMapper careDetailMapper;
    private final PatientBaseInfoMapper patientBaseInfoMapper;
    private final MedicalRecordMapper medicalRecordMapper;
    private final MedicationSummaryMapper summaryMapper;
    // 数据填充列表
    List<Map<String, Object>> careRecordList = null;
    // 出院教育西药列表
    List<Map<String, Object>> eduWestRecordList = null;
    // 出院教育中药饮片列表
    List<Map<String, Object>> educTraditionalRecordList = null;

    /**
     * 查询药学监护记录
     */
    @Override
    public PharmaceuticalCareVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询药学监护记录列表
     */
    @Override
    public TableDataInfo<PharmaceuticalCareVo> queryPageList(PharmaceuticalCareBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PharmaceuticalCare> lqw = buildQueryWrapper(bo);
        Page<PharmaceuticalCareVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询药学监护记录列表
     */
    @Override
    public List<PharmaceuticalCareVo> queryList(PharmaceuticalCareBo bo) {
        LambdaQueryWrapper<PharmaceuticalCare> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PharmaceuticalCare> buildQueryWrapper(PharmaceuticalCareBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PharmaceuticalCare> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getMedicalRecordNo() != null, PharmaceuticalCare::getMedicalRecordNo, bo.getMedicalRecordNo());
        lqw.eq(StringUtils.isNotBlank(bo.getDischargePharmacyEducation()), PharmaceuticalCare::getDischargePharmacyEducation, bo.getDischargePharmacyEducation());
        return lqw;
    }

    /**
     * 新增药学监护记录
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public R<Void> insertByBo(PharmaceuticalCareBo bo) {
        // 查询登录信息
        LoginUser loginUser = LoginHelper.getLoginUser();
        // 查询药学监护记录
        PharmaceuticalCare existPharmaceuticalCare = baseMapper.selectOne(new LambdaQueryWrapper<PharmaceuticalCare>()
            .eq(PharmaceuticalCare::getMedicalRecordNo, bo.getMedicalRecordNo())
            .select(PharmaceuticalCare::getId));
        // 保存药学监护记录
        PharmaceuticalCare pharmaceuticalCare = BeanUtil.toBean(bo, PharmaceuticalCare.class);
        if (ObjectUtil.isNotNull(existPharmaceuticalCare))
            pharmaceuticalCare.setId(existPharmaceuticalCare.getId());
        if (ObjectUtil.isNull(bo.getId())) {
            baseMapper.insert(pharmaceuticalCare);
        } else {
            baseMapper.updateById(pharmaceuticalCare);
        }
        // 删除药学监护详情
        careDetailMapper.delete(new LambdaQueryWrapper<PharmaceuticalCareDetail>()
            .eq(PharmaceuticalCareDetail::getMedicalRecordNo, bo.getMedicalRecordNo())
            .ne(PharmaceuticalCareDetail::getCreateBy, "HIS")
            .ne(PharmaceuticalCareDetail::getUpdateBy, "HIS"));
        // 获取药学监护详情集合
        List<PharmaceuticalCareDetailBo> careDetailBoList = bo.getPharmaceuticalCareDetailBoList();
        // 保存和更新药学监护详情
        if (ObjectUtil.isNotNull(careDetailBoList) && careDetailBoList.size() > 0) {
            // 处理药物治疗方案的数据
            careDetailBoList.stream().forEach(pharmaceuticalCareDetailBo -> {
                // 获取药物治疗方案调整的集合
                List<MedicalRecordBo> careDetailMedicalList = pharmaceuticalCareDetailBo.getCareDetailMedicalList();
                if (ObjectUtil.isNull(careDetailMedicalList) || careDetailMedicalList.size() == 0) {
                    pharmaceuticalCareDetailBo.setSchemeAdjustment("");
                } else { // 不为空
                    StringBuilder sb = new StringBuilder();
                    careDetailMedicalList.stream().forEach(medicalRecordBo -> {
                        StringBuilder sb2 = new StringBuilder();
                        sb2.append(medicalRecordBo.getPurpose() + "~"); // 用药调整状态
                        sb2.append(medicalRecordBo.getPillsName() + "~"); // 用药目的
                        sb2.append(medicalRecordBo.getAmountPer() + "~"); // 单次剂量
                        sb2.append(medicalRecordBo.getPillsUsage() + "~"); // 用法
                        sb2.append(medicalRecordBo.getFrequency() + "~"); // 频次
                        sb2.append(medicalRecordBo.getBeginDate() + "~"); // 起始日期
                        sb2.append(medicalRecordBo.getPillsCycle()); // 备注
                        sb.append(sb2.toString() + "&");
                    });
                    String schemeAdjustment = sb.toString();
                    schemeAdjustment = schemeAdjustment.substring(0, schemeAdjustment.length() - 1);
                    pharmaceuticalCareDetailBo.setSchemeAdjustment(schemeAdjustment);
                }
                // 处理中药饮片调整方案的数据
                List<MedicalRecordBo> traditionalMedicalBoList = pharmaceuticalCareDetailBo.getTraditionalMedicalList();
                if (ObjectUtil.isNull(traditionalMedicalBoList) || traditionalMedicalBoList.size() == 0) { // 中药饮片调整方案为空
                    pharmaceuticalCareDetailBo.setTraditionalPills("");
                } else { // 中药饮片调整方案不为空
                    StringBuilder sb = new StringBuilder();
                    traditionalMedicalBoList.stream().forEach(medicalRecordBo -> {
                        StringBuilder sb2 = new StringBuilder();
                        sb2.append(medicalRecordBo.getPurpose() + "~"); // 中药饮片调整状态
                        sb2.append(medicalRecordBo.getPillsName() + "~"); // 用药目的
                        sb2.append(medicalRecordBo.getPillsUsage() + "~"); // 用法用量
                        sb2.append(medicalRecordBo.getBeginDate() + "~"); // 起始日期
                        sb2.append(medicalRecordBo.getEndDate()); // 结束日期
                        sb.append(sb2.toString() + "&");
                    });
                    String traditionalPills = sb.toString();
                    traditionalPills = traditionalPills.substring(0, traditionalPills.length() - 1);
                    pharmaceuticalCareDetailBo.setTraditionalPills(traditionalPills);
                }
            });
            // 保存药学监护详情
            List<PharmaceuticalCareDetail> careDetailList = BeanUtil.copyToList(careDetailBoList, PharmaceuticalCareDetail.class);
            // 过滤掉HIS接受的数据
            List<PharmaceuticalCareDetail> collect = careDetailList.stream().filter(pharmaceuticalCareDetail -> !"HIS".equals(pharmaceuticalCareDetail.getCreateBy())
                && !"HIS".equals(pharmaceuticalCareDetail.getUpdateBy()))
                .collect(Collectors.toList());
            careDetailMapper.insertBatch(collect);
            // 更新HIS接受数据的其它字段值
            List<PharmaceuticalCareDetail> collectHIS = careDetailList.stream().filter(pharmaceuticalCareDetail -> "HIS".equals(pharmaceuticalCareDetail.getCreateBy()))
                .collect(Collectors.toList());
            if (collectHIS.size() > 0) {
                collectHIS.stream().forEach(pharmaceuticalCareDetail -> {
                    pharmaceuticalCareDetail.setVitalSigns(null);
                });
                careDetailMapper.updateBatchById(collectHIS);
            }
        }
        // 删除出院用药集合
        medicalRecordMapper.delete(new LambdaQueryWrapper<MedicalRecord>()
            .eq(MedicalRecord::getMedicalRecordNo, bo.getMedicalRecordNo())
            .in(MedicalRecord::getMedicalType, DictConstants.MEDICAL_TYPE_EDU_WEST, DictConstants.MEDICAL_TYPE_EDU_TRADITIONAL));
        // 保存出院西药信息
        List<MedicalRecordBo> educWestMedicalRecordBoList = bo.getEducWestMedicalRecordList();
        if (ObjectUtil.isNotNull(educWestMedicalRecordBoList) && educWestMedicalRecordBoList.size() > 0) {
            List<MedicalRecord> educWestMedicalRecordList = BeanUtil.copyToList(educWestMedicalRecordBoList, MedicalRecord.class);
            medicalRecordMapper.insertBatch(educWestMedicalRecordList);
        }
        // 保存出院中药饮片信息
        List<MedicalRecordBo> educTraditionalMedicalRecordBoList = bo.getEducTraditionalMedicalRecordList();
        if (ObjectUtil.isNotNull(educTraditionalMedicalRecordBoList) && educTraditionalMedicalRecordBoList.size() > 0) {
            List<MedicalRecord> educTraditionalMedicalRecordList = BeanUtil.copyToList(educTraditionalMedicalRecordBoList, MedicalRecord.class);
            medicalRecordMapper.insertBatch(educTraditionalMedicalRecordList);
        }
        // 查询药历小结信息
        MedicationSummary medicationSummary = summaryMapper.selectOne(new LambdaQueryWrapper<MedicationSummary>()
            .eq(MedicationSummary::getMedicalRecordNo, bo.getMedicalRecordNo()));
        PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
            .eq(PatientBaseInfo::getMedicalRecordNo, bo.getMedicalRecordNo())
            .select(PatientBaseInfo::getAdmissionTime, PatientBaseInfo::getDischargeTime));
        if (ObjectUtil.isNull(medicationSummary) && ObjectUtil.isNotNull(patientBaseInfo.getDischargeTime())) {
            // 新增药历小结
            medicationSummary = new MedicationSummary();
            medicationSummary.setMedicalRecordNo(bo.getMedicalRecordNo());
            medicationSummary.setInHospitalDate(patientBaseInfo.getAdmissionTime().toLocalDate());
            medicationSummary.setOutHospitalDate(patientBaseInfo.getDischargeTime().toLocalDate());
            medicationSummary.setSummaryState("0"); // 0未完成 1已完成
            if (careDetailBoList.size() > 0) {
                medicationSummary.setSigner(careDetailBoList.get(0).getSigner());
            }
            summaryMapper.insert(medicationSummary);
        }
        return R.ok("保存成功");
    }

    /**
     * 修改药学监护记录
     */
    @Override
    public Boolean updateByBo(PharmaceuticalCareBo bo) {
        PharmaceuticalCare update = BeanUtil.toBean(bo, PharmaceuticalCare.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PharmaceuticalCare entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除药学监护记录
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 查询药学监护记录
     *
     * @param medicalRecordNo 病历号
     * @return
     */
    @Override
    public PharmaceuticalCareVo queryByMedicalRecordNo(Integer medicalRecordNo) {
        // 创建药学监护视图对象
        PharmaceuticalCareVo pharmaceuticalCareVo = new PharmaceuticalCareVo();
        // 查询药学监护信息
        PharmaceuticalCare pharmaceuticalCare = baseMapper.selectOne(new LambdaQueryWrapper<PharmaceuticalCare>()
            .eq(PharmaceuticalCare::getMedicalRecordNo, medicalRecordNo));
        if (ObjectUtil.isNotNull(pharmaceuticalCare)) {
            pharmaceuticalCareVo = BeanUtil.toBean(pharmaceuticalCare, PharmaceuticalCareVo.class);
        }
        // 查询患者入院时间
        PatientBaseInfoVo patientBaseInfoVo = patientBaseInfoMapper.selectVoOne(new LambdaQueryWrapper<PatientBaseInfo>()
            .eq(PatientBaseInfo::getMedicalRecordNo, medicalRecordNo)
            .select(PatientBaseInfo::getAdmissionTime));
        if (ObjectUtil.isNotNull(patientBaseInfoVo)) {
            pharmaceuticalCareVo.setAdmissionDate(patientBaseInfoVo.getAdmissionTime().toLocalDate());
        }
        // 查询药学监护详情集合
        List<PharmaceuticalCareDetailVo> pharmaceuticalCareDetailVoList = careDetailMapper.selectVoList(new LambdaQueryWrapper<PharmaceuticalCareDetail>()
            .eq(PharmaceuticalCareDetail::getMedicalRecordNo, medicalRecordNo)
            .orderByAsc(PharmaceuticalCareDetail::getCareDate));
        // 封装药物调整方案的数据集合
        pharmaceuticalCareDetailVoList.stream().forEach(pharmaceuticalCareDetailVo -> {
            // 西药调整方案
            List<MedicalRecordVo> careDetailMedicalList = new ArrayList<>();
            String schemeAdjustment = pharmaceuticalCareDetailVo.getSchemeAdjustment();
            if (StringUtils.isNotBlank(schemeAdjustment)) {
                String[] split = schemeAdjustment.split("&");
                for (int i = 0; i < split.length; i++) {
                    String[] itemSplit = split[i].split("~");
                    if (itemSplit.length > 0) {
                        MedicalRecordVo medicalRecordVo = new MedicalRecordVo();
                        medicalRecordVo.setPurpose(itemSplit[0]); // 用药调整
                        medicalRecordVo.setPillsName(itemSplit[1]); // 药物名称
                        medicalRecordVo.setAmountPer(itemSplit[2]); // 单次剂量
                        medicalRecordVo.setPillsUsage(itemSplit[3]); // 用法
                        medicalRecordVo.setFrequency(itemSplit[4]); // 频次
                        if (!"null".equals(itemSplit[5])) {
                            medicalRecordVo.setBeginDate(LocalDateTime.parse(itemSplit[5])); // 开始日期
                        }
                        if (itemSplit.length == 7) {
                            medicalRecordVo.setPillsCycle(itemSplit[6]); // 备注
                        }
                        careDetailMedicalList.add(medicalRecordVo);
                    }
                }
            }
            pharmaceuticalCareDetailVo.setCareDetailMedicalList(careDetailMedicalList);
            // 中药饮片调整方案
            List<MedicalRecordVo> traditionalMedicalVoList = new ArrayList<>();
            String traditionalPills = pharmaceuticalCareDetailVo.getTraditionalPills();
            if (StringUtils.isNotBlank(traditionalPills)) {
                String[] split = traditionalPills.split("&");
                for (int i = 0; i < split.length; i++) {
                    String[] itemSplit = split[i].split("~");
                    if (itemSplit.length > 0) {
                        MedicalRecordVo medicalRecordVo = new MedicalRecordVo();
                        medicalRecordVo.setPurpose(itemSplit[0]); // 用药调整
                        medicalRecordVo.setPillsName(itemSplit[1]); // 药物名称
                        medicalRecordVo.setPillsUsage(itemSplit[2]); // 用法用量
                        if (!StringUtils.equals(itemSplit[3], "null")) {
                            medicalRecordVo.setBeginDate(LocalDateTime.parse(itemSplit[3])); // 起始日期
                        }
                        if (itemSplit.length == 5 && !StringUtils.equals(itemSplit[4], "null")) {
                            medicalRecordVo.setEndDate(LocalDateTime.parse(itemSplit[4])); // 结束日期
                        }
                        traditionalMedicalVoList.add(medicalRecordVo);
                    }
                }
            }
            pharmaceuticalCareDetailVo.setTraditionalMedicalList(traditionalMedicalVoList);
        });
        // HIS同一天生命体征子项按时间分组
        if (pharmaceuticalCareDetailVoList.size() > 0) {
            pharmaceuticalCareDetailVoList.stream().forEach(pharmaceuticalCareDetailVo -> {
                if ("HIS".equals(pharmaceuticalCareDetailVo.getCreateBy())) {
                    Set<String> timeSet = new HashSet<>();
                    String vitalSigns = pharmaceuticalCareDetailVo.getVitalSigns();
                    List<String> vitalSignsItemList = Arrays.asList(vitalSigns.split("、"));
                    vitalSignsItemList.stream().forEach(s -> {
                        String[] split = s.split("时间：");
                        timeSet.add(split[1]);
                    });
                    // Set转化成List
                    List<String> timeList = new ArrayList(timeSet);
                    Collections.sort(timeList);
                    if (timeList.size() == 1) {
                        String s = pharmaceuticalCareDetailVo.getVitalSigns().replaceAll("时间：" + timeList.get(0), "");
                        pharmaceuticalCareDetailVo.setVitalSigns("时间：" + timeList.get(0) + " " + s);
                    } else {
                        StringBuilder sb = new StringBuilder();
                        timeList.stream().forEach(s -> {
                            // 过滤出某一时间的生命体征数据
                            List<String> list = vitalSignsItemList.stream().filter(vitalItem -> vitalItem.contains(s)).collect(Collectors.toList());
                            String collect = list.stream().collect(Collectors.joining("、"));
                            sb.append("时间：" + s + " " + collect.replaceAll("时间：" + s, "") + System.getProperty("line.separator"));
                        });
                        String vitalSignItem = sb.toString();
                        pharmaceuticalCareDetailVo.setVitalSigns(vitalSignItem.substring(0, vitalSignItem.length() - 2));
                    }
                }
            });
        }
        // 血压显示格式：收缩压/舒张压mmHg
        pharmaceuticalCareDetailVoList.stream().forEach(pharmaceuticalCareDetailVo -> {
            String vitalSigns = pharmaceuticalCareDetailVo.getVitalSigns();
            vitalSigns = vitalSigns.replaceAll("收缩压：", "血压：").replaceAll("mmhg-毫米汞柱", "mmHg").replaceAll("mmHg 、舒张压：", "/");
            pharmaceuticalCareDetailVo.setVitalSigns(vitalSigns);
        });
        pharmaceuticalCareVo.setPharmaceuticalCareDetailVoList(pharmaceuticalCareDetailVoList);
        // 查询出院用药集合
        List<MedicalRecordVo> outMedicalRecordVoList = medicalRecordMapper.selectVoList(new LambdaQueryWrapper<MedicalRecord>()
            .eq(MedicalRecord::getMedicalRecordNo, medicalRecordNo)
            .in(MedicalRecord::getMedicalType, DictConstants.MEDICAL_TYPE_EDU_WEST, DictConstants.MEDICAL_TYPE_EDU_TRADITIONAL));
        // 封装出院用药西药集合
        pharmaceuticalCareVo.setEducWestMedicalRecordList(outMedicalRecordVoList.stream().filter(medicalRecordVo -> medicalRecordVo.getMedicalType().equals(DictConstants.MEDICAL_TYPE_EDU_WEST)).collect(Collectors.toList()));
        // 封装出院用药中药饮片集合
        pharmaceuticalCareVo.setEducTraditionalMedicalRecordList(outMedicalRecordVoList.stream().filter(medicalRecordVo -> medicalRecordVo.getMedicalType().equals(DictConstants.MEDICAL_TYPE_EDU_TRADITIONAL)).collect(Collectors.toList()));
        return pharmaceuticalCareVo;
    }

    /**
     * 下载出院用药教育
     *
     * @param response
     * @param medicalRecordNo 药历号
     */
    @Override
    public void exportWord(HttpServletResponse response, Integer medicalRecordNo) {
        try {
            Map<String, Object> datas = getEducationMap(medicalRecordNo);
            // html渲染插件
            HtmlRenderPolicy policy = new HtmlRenderPolicy();
            // 循环渲染插件
            LoopRowTableRenderPolicy policy2 = new LoopRowTableRenderPolicy();
            Configure configure = Configure.builder()
                // 注册html解析插件
                .bind("dischargePharmacyEducation", policy)
                // 循环渲染插件
                .bind("educWestRecordList", policy2)
                .bind("educTraditionalRecordList", policy2)
                .build();
            // 查询出院用药教育信息并映射数据Map
            PharmaceuticalCareVo pharmaceuticalCareVo = baseMapper.selectVoOne(new LambdaQueryWrapper<PharmaceuticalCare>().eq(PharmaceuticalCare::getMedicalRecordNo, medicalRecordNo));
            if (ObjectUtil.isNotNull(pharmaceuticalCareVo)) {
                datas.put("dischargePharmacyEducation", pharmaceuticalCareVo.getDischargePharmacyEducation());
            }
            // 查询患者基本信息
            String patientName = null;
            PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
                .eq(PatientBaseInfo::getMedicalRecordNo, medicalRecordNo)
                .select(PatientBaseInfo::getPatientName));
            if (ObjectUtil.isNotNull(patientBaseInfo)) {
                patientName = patientBaseInfo.getPatientName();
            }
            // 读取模板渲染数据
            ResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource("classpath:template/discharge_pharmacy_education.docx");
            InputStream inputStream = resource.getInputStream();
            XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(datas);
            // 下载word文档
            PoiTlUtils.createOutPusStream(response, template, medicalRecordNo + "-" + patientName + "-出院用药教育");
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 获取出院教育Map数据
     *
     * @param medicalRecordNo 流水号
     * @return
     */
    @Override
    public Map<String, Object> getEducationMap(Integer medicalRecordNo) {
        // 映射数据Map
        Map<String, Object> datas = new HashMap<String, Object>();
        // 初始化列表对象
        eduWestRecordList = new ArrayList<>();
        educTraditionalRecordList = new ArrayList<>();
        // 出院教育西医用药汇总信息
        List<MedicalRecordVo> eduWestRecordVoList = medicalRecordMapper.selectVoList(new LambdaQueryWrapper<MedicalRecord>()
            .eq(MedicalRecord::getMedicalRecordNo, medicalRecordNo)
            .eq(MedicalRecord::getMedicalType, DictConstants.MEDICAL_TYPE_EDU_WEST));
        eduWestRecordVoList.stream().forEach(medicalRecordVo -> {
            // 封装西药数据到Map
            Map<String, Object> map = new HashMap<>();
            map.put("purpose", medicalRecordVo.getPurpose());
            map.put("pillsName", medicalRecordVo.getPillsName());
            map.put("amountPer", medicalRecordVo.getAmountPer());
            map.put("pillsUsage", medicalRecordVo.getPillsUsage());
            map.put("frequency", medicalRecordVo.getFrequency());
            if ("Y".equals(medicalRecordVo.getIsContinue())) {
                map.put("isContinue", "是");
            } else if ("N".equals(medicalRecordVo.getIsContinue())) {
                map.put("isContinue", "否");
            } else {
                map.put("isContinue", "");
            }
            LocalDateTime beginDateTime = medicalRecordVo.getBeginDate();
            LocalDateTime endDateTime = medicalRecordVo.getEndDate();
            String beginDate = "";
            String endDate = "";
            if (ObjectUtil.isNotNull(beginDateTime))
                beginDate = beginDateTime.toLocalDate().toString();
            map.put("beginDate", beginDate);
            map.put("pillsCycle", medicalRecordVo.getPillsCycle());
            eduWestRecordList.add(map);
        });
        datas.put("educWestRecordList", eduWestRecordList);
        // 查询出院教育中药饮片汇总信息
        List<MedicalRecordVo> eduTraditionalRecordVoList = medicalRecordMapper.selectVoList(new LambdaQueryWrapper<MedicalRecord>()
            .eq(MedicalRecord::getMedicalRecordNo, medicalRecordNo)
            .eq(MedicalRecord::getMedicalType, DictConstants.MEDICAL_TYPE_EDU_TRADITIONAL));
        eduTraditionalRecordVoList.stream().forEach(medicalRecordVo -> {
            // 封装中药饮片数据到Map
            Map<String, Object> map = new HashMap<>();
            map.put("purpose", medicalRecordVo.getPurpose());
            map.put("pillsName", medicalRecordVo.getPillsName());
            map.put("pillsUsage", medicalRecordVo.getPillsUsage());
            if (ObjectUtil.isNotNull(medicalRecordVo.getBeginDate()))
                map.put("beginDate", medicalRecordVo.getBeginDate().toLocalDate());
            if (ObjectUtil.isNotNull(medicalRecordVo.getEndDate()))
                map.put("endDate", medicalRecordVo.getEndDate().toLocalDate());
            map.put("pillsCycle", medicalRecordVo.getPillsCycle());
            educTraditionalRecordList.add(map);
        });
        datas.put("educTraditionalRecordList", educTraditionalRecordList);
        return datas;
    }

    /**
     * 下载药学监护记录
     *
     * @param response
     * @param medicalRecordNo 药历号
     */
    @Override
    public void exportPharmaceuticalCareRecord(HttpServletResponse response, Integer medicalRecordNo) {
        // 获取药学监护记录map数据
        Map<String, Object> datas = getPharmaceuticalCareMap(medicalRecordNo);
        // 列表渲染插件
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure configure = Configure.builder()
            .bind("careRecordList", policy)
            .bind("careWestRecordList", policy)
            .bind("careTraditionalRecordList", policy)
            .build();
        datas.put("careRecordList", careRecordList);
        try {
            // 读取模板渲染数据
            ResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource("classpath:template/pharmaceutical_care_record.docx");
            InputStream inputStream = null;
            inputStream = resource.getInputStream();
            XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(datas);
            // 查询患者基本信息
            String patientName = null;
            PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
                .eq(PatientBaseInfo::getMedicalRecordNo, medicalRecordNo)
                .select(PatientBaseInfo::getPatientName));
            if (ObjectUtil.isNotNull(patientBaseInfo)) {
                patientName = patientBaseInfo.getPatientName();
            }
            // 下载word文档
            PoiTlUtils.createOutPusStream(response, template, medicalRecordNo + "-" + patientName + "-药学监护记录");
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 获取药学监护下载集合
     *
     * @param medicalRecordNo 药历号
     * @return
     */
    @Override
    public Map<String, Object> getPharmaceuticalCareMap(Integer medicalRecordNo) {
        // 映射数据Map
        Map<String, Object> datas = new HashMap<String, Object>();
        // 实体化列表对象
        careRecordList = new ArrayList<>();
        // 查询药学监护记录
        List<PharmaceuticalCareDetailVo> pharmaceuticalCareDetailVoList = careDetailMapper.selectVoList(new LambdaQueryWrapper<PharmaceuticalCareDetail>()
            .eq(PharmaceuticalCareDetail::getMedicalRecordNo, medicalRecordNo));
        // 按时间分组
        // HIS同一天生命体征子项按时间分组
        if (pharmaceuticalCareDetailVoList.size() > 0) {
            pharmaceuticalCareDetailVoList.stream().forEach(pharmaceuticalCareDetailVo -> {
                if ("HIS".equals(pharmaceuticalCareDetailVo.getCreateBy())) {
                    Set<String> timeSet = new HashSet<>();
                    String vitalSigns = pharmaceuticalCareDetailVo.getVitalSigns();
                    List<String> vitalSignsItemList = Arrays.asList(vitalSigns.split("、"));
                    vitalSignsItemList.stream().forEach(s -> {
                        String[] split = s.split("时间：");
                        timeSet.add(split[1]);
                    });
                    // Set转化成List
                    List<String> timeList = new ArrayList(timeSet);
                    Collections.sort(timeList);
                    if (timeList.size() == 1) {
                        String s = pharmaceuticalCareDetailVo.getVitalSigns().replaceAll("时间：" + timeList.get(0), "");
                        pharmaceuticalCareDetailVo.setVitalSigns("时间：" + timeList.get(0) + " " + s);
                    } else {
                        StringBuilder sb = new StringBuilder();
                        timeList.stream().forEach(s -> {
                            // 过滤出某一时间的生命体征数据
                            List<String> list = vitalSignsItemList.stream().filter(vitalItem -> vitalItem.contains(s)).collect(Collectors.toList());
                            String collect = list.stream().collect(Collectors.joining("、"));
                            sb.append("时间：" + s + " " + collect.replaceAll("时间：" + s, "") + System.getProperty("line.separator"));
                        });
                        String vitalSignItem = sb.toString();
                        pharmaceuticalCareDetailVo.setVitalSigns(vitalSignItem.substring(0, vitalSignItem.length() - 2));
                    }
                }
            });
        }
        // 下载需要的数据
        if (ObjectUtil.isNotNull(pharmaceuticalCareDetailVoList) && pharmaceuticalCareDetailVoList.size() > 0) {
            pharmaceuticalCareDetailVoList.stream().forEach(pharmaceuticalCareDetailVo -> {
                // 封装数据
                Map<String, Object> map = new HashMap<>();
                map.put("year", pharmaceuticalCareDetailVo.getCareDate().getYear());
                map.put("month", pharmaceuticalCareDetailVo.getCareDate().getMonthValue());
                map.put("day", pharmaceuticalCareDetailVo.getCareDate().getDayOfMonth());
                map.put("inHospitalDays", pharmaceuticalCareDetailVo.getInHospitalDays());
                map.put("vitalSigns", pharmaceuticalCareDetailVo.getVitalSigns().replaceAll("收缩压：", "血压：").replaceAll("mmhg-毫米汞柱", "mmHg").replaceAll("mmHg 、舒张压：", "/"));
                map.put("executiveCondition", pharmaceuticalCareDetailVo.getExecutiveCondition());
                map.put("schemeAdjustment", pharmaceuticalCareDetailVo.getSchemeAdjustment());
                map.put("signer", pharmaceuticalCareDetailVo.getSigner());
                map.put("pillsEducation", pharmaceuticalCareDetailVo.getPillsEducation());
                String guardianLevel = pharmaceuticalCareDetailVo.getGuardianLevel();
                if (StringUtils.equals("0", guardianLevel)) {
                    guardianLevel = "一级";
                } else if (StringUtils.equals("1", guardianLevel)) {
                    guardianLevel = "二级";
                } else {
                    guardianLevel = "三级";
                }
                map.put("guardianLevel", guardianLevel);
                if (StringUtils.equals("true", pharmaceuticalCareDetailVo.getPillsEducationOption())) {
                    map.put("pillsEducationOption", true);
                    if (StringUtils.isBlank(pharmaceuticalCareDetailVo.getPillsEducation())) {
                        map.put("notShowPillEducation", true);
                    }
                } else {
                    map.put("pillsEducationOption", false);
                }
                map.put("pillsSuggest", pharmaceuticalCareDetailVo.getPillsSuggest());
                if (StringUtils.equals("true", pharmaceuticalCareDetailVo.getMedicationSummaryOption3())) {
                    map.put("showPillSuggest", true);
                    map.put("notShowPillSuggest", false);
                } else {
                    map.put("showPillSuggest", false);
                    map.put("notShowPillSuggest", true);
                }
                // 查询患者出院日期
                PatientBaseInfoVo patientBaseInfoVo = patientBaseInfoMapper.selectVoOne(new LambdaQueryWrapper<PatientBaseInfo>()
                    .eq(PatientBaseInfo::getMedicalRecordNo, pharmaceuticalCareDetailVo.getMedicalRecordNo())
                    .select(PatientBaseInfo::getDischargeTime));
                if (ObjectUtil.isNotNull(patientBaseInfoVo)) {
                    LocalDateTime dischargeTime = patientBaseInfoVo.getDischargeTime();
                    if (ObjectUtil.isNotNull(dischargeTime)) {
                        LocalDate disChargeDate = dischargeTime.toLocalDate(); // 出院日期
                        if (disChargeDate.equals(pharmaceuticalCareDetailVo.getCareDate())) {
                            map.put("outHospital", "（出院）");
                        }
                    }
                }
                // 西药调整方案
                List<MedicalRecordVo> careWestList = new ArrayList<>();
                String schemeAdjustment = pharmaceuticalCareDetailVo.getSchemeAdjustment();
                if (StringUtils.isNotBlank(schemeAdjustment)) {
                    String[] split = schemeAdjustment.split("&");
                    for (int i = 0; i < split.length; i++) {
                        String[] itemSplit = split[i].split("~");
                        if (itemSplit.length > 0) {
                            MedicalRecordVo medicalRecordVo = new MedicalRecordVo();
                            medicalRecordVo.setPurpose(itemSplit[0]); // 用药调整
                            medicalRecordVo.setPillsName(itemSplit[1]); // 药物名称
                            medicalRecordVo.setAmountPer(itemSplit[2]); // 单次剂量
                            medicalRecordVo.setPillsUsage(itemSplit[3]); // 用法
                            medicalRecordVo.setFrequency(itemSplit[4]); // 频次
                            if (!"null".equals(itemSplit[5])) {
                                medicalRecordVo.setPillsCycle(itemSplit[5].split("T")[0]); // 起始日期
                            }
                            careWestList.add(medicalRecordVo);
                        }
                    }
                }
                if (careWestList.size() > 0) {
                    map.put("showWest", true);
                    map.put("careWestRecordList", careWestList);
                } else {
                    map.put("showWest", false);
                }

                // 中药饮片调整方案
                List<MedicalRecordVo> careTraditionalList = new ArrayList<>();
                String traditionalPills = pharmaceuticalCareDetailVo.getTraditionalPills();
                if (StringUtils.isNotBlank(traditionalPills)) {
                    String[] split = traditionalPills.split("&");
                    for (int i = 0; i < split.length; i++) {
                        String[] itemSplit = split[i].split("~");
                        if (itemSplit.length > 0) {
                            MedicalRecordVo medicalRecordVo = new MedicalRecordVo();
                            medicalRecordVo.setPurpose(itemSplit[0]); // 用药调整
                            medicalRecordVo.setPillsName(itemSplit[1]); // 药物名称
                            medicalRecordVo.setPillsUsage(itemSplit[2]); // 用法用量
                            if (!StringUtils.equals(itemSplit[3], "null")) {
                                medicalRecordVo.setPillsCycle(itemSplit[3].split("T")[0]); // 起始日期
                            }
                            if (itemSplit.length == 5 && !StringUtils.equals(itemSplit[4], "null")) { // 结束日期
                                medicalRecordVo.setEndDateStr(itemSplit[4].split("T")[0]);
                            }
                            careTraditionalList.add(medicalRecordVo);
                        }
                    }
                }
                if (careTraditionalList.size() > 0) {
                    map.put("showTraditional", true);
                    map.put("careTraditionalRecordList", careTraditionalList);
                } else {
                    map.put("showTraditional", false);
                }
                map.put("carePlanAdjustment", pharmaceuticalCareDetailVo.getCarePlanAdjustment());
                if (StringUtils.equals("true", pharmaceuticalCareDetailVo.getCarePlanAdjustmentOption())) {
                    map.put("carePlanAdjustmentOption", true);
                    if (StringUtils.isBlank(pharmaceuticalCareDetailVo.getCarePlanAdjustment())) {
                        map.put("notShowCarePlan", true);
                    }
                } else {
                    map.put("carePlanAdjustmentOption", false);
                }
                careRecordList.add(map);
            });
        }
        datas.put("careRecordList", careRecordList);
        return datas;
    }

    /**
     * 根据ID删除监护记录
     *
     * @param id 药学监护详情id
     * @return
     */
    @Override
    public R<Void> removeById(Long id) {
        return careDetailMapper.deleteById(id) > 0 ? R.ok("删除成功") : R.fail("删除失败");
    }
}
